package com.mdd.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mdd.common.entity.*;
import com.mdd.common.entity.user.User;
import com.mdd.common.enums.EngineerEnum;
import com.mdd.common.exception.OperateException;
import com.mdd.common.mapper.DevRegionMapper;
import com.mdd.common.mapper.engineer.*;
import com.mdd.common.mapper.user.UserMapper;
import com.mdd.common.service.EngineerService;
import com.mdd.common.util.StringUtils;
import com.mdd.common.util.TimeUtils;
import com.mdd.common.util.UrlUtils;
import com.mdd.common.validate.engineer.EngineerApplyValidate;
import com.mdd.common.vo.engineer.EngineerApplyDetailVo;
import com.mdd.common.vo.engineer.EngineerConfigVo;
import com.mdd.common.vo.engineer.EngineerIndexVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
public class EngineerServiceImpl implements EngineerService {

    @Resource
    EngineerConfigMapper engineerConfigMapper;

    @Resource
    EngineerMapper engineerMapper;

    @Resource
    EngineerApplyMapper engineerApplyMapper;

    @Resource
    UserMapper userMapper;

    @Resource
    EngineerLevelMapper engineerLevelMapper;

    @Resource
    EngineerOrderMapper engineerOrderMapper;

    @Resource
    DevRegionMapper devRegionMapper;

    @Override
    public EngineerConfigVo config() {
        QueryWrapper<EngineerConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);
        List<EngineerConfig> list = engineerConfigMapper.selectList(queryWrapper);

        Map<String, String> map = new LinkedHashMap<>();
        for (EngineerConfig config : list) {
            map.put(config.getName(), StringUtils.isNotNull(config.getValue()) ? config.getValue().trim() : null);
        }

        EngineerConfigVo vo = new EngineerConfigVo();
        vo.setOpen(Integer.parseInt(map.getOrDefault("open", "0")));
        vo.setLevel(Integer.parseInt(map.getOrDefault("level", "1")));
        vo.setIsSelfRebate(Integer.parseInt(map.getOrDefault("isSelfRebate", "0")));
        vo.setIsEarningsShow(Integer.parseInt(map.getOrDefault("isEarningsShow", "0")));
        vo.setIsEarningsScope(Integer.parseInt(map.getOrDefault("isEarningsScope", "0")));
        vo.setOpenCondition(Integer.parseInt(map.getOrDefault("openCondition", "0")));
        vo.setProtocolShow(Integer.parseInt(map.getOrDefault("protocolShow", "0")));
        vo.setProtocolContent(map.getOrDefault("protocolContent", ""));
        vo.setApplyImage(UrlUtils.toAbsoluteUrl(map.getOrDefault("applyImage", "")));
        vo.setEarningsCalMethod(Integer.parseInt(map.getOrDefault("earningsCalMethod", "1")));
        vo.setSettlementTiming(Integer.parseInt(map.getOrDefault("settlementTiming", "1")));
        vo.setSettlementTime(map.getOrDefault("settlementTime", "0"));
        return vo;
    }

    @Override
    public void apply(Integer userId, EngineerApplyValidate applyValidate) {
        // 分销是否开启
        EngineerConfigVo config = config();
        if (config.getOpen().equals(0)) {
            throw new OperateException("师傅分销功能已关闭");
        }
        if (!config.getOpenCondition().equals(2)) {
            throw new OperateException("暂不可申请");
        }

        // 是否已是入驻师傅
        Engineer engineer = engineerMapper.selectOne(new QueryWrapper<Engineer>().eq("user_Id", userId).last("limit 1"));
        if (engineer != null && engineer.getIsEngineer() > 0) {
            throw new OperateException("您已是入驻师傅，无需申请");
        }

        // 是否已有审核中的申请记录
        EngineerApply engineerApply = engineerApplyMapper.selectOne(new QueryWrapper<EngineerApply>().eq("user_Id", userId).last("limit 1"));
        if (engineerApply != null && engineerApply.getStatus().equals(EngineerEnum.APPLY_STATUS_ING.getCode())) {
            throw new OperateException("审核中,请勿重复提交申请");
        }

        // 生成申请记录
        EngineerApply applyData = new EngineerApply();
        applyData.setUserId(userId);
        applyData.setRealName(applyValidate.getRealName());
        applyData.setMobile(applyValidate.getMobile());
        applyData.setProvince(applyValidate.getProvince());
        applyData.setCity(applyValidate.getCity());
        applyData.setDistrict(applyValidate.getDistrict());
        applyData.setReason(applyValidate.getReason());
        applyData.setStatus(EngineerEnum.APPLY_STATUS_ING.getCode());
        applyData.setCreateTime(TimeUtils.timestamp());
        applyData.setUpdateTime(TimeUtils.timestamp());
        engineerApplyMapper.insert(applyData);
    }

    @Override
    public EngineerIndexVo index(Integer userId) {
        User user = userMapper.selectById(userId);
        Assert.notNull(user, "用户信息不存在");

        // 分销配置
        EngineerConfigVo config = config();

        EngineerIndexVo vo = new EngineerIndexVo();
        vo.setId(user.getId());
        vo.setCode(user.getCode());
        vo.setEarnings(user.getEarnings());

        // 是否为分销会员
        int isDistribution = 1;
        // 是否显示分销申请页
        int isShowApplyPage = 0;
        Engineer engineer = engineerMapper.selectOne(new QueryWrapper<Engineer>().eq("user_id", userId).last("limit 1"));

        if (engineer == null || engineer.getIsEngineer().equals(0)) {
            isDistribution = 0;
        } else {
            if (engineer.getLevelId() != null && engineer.getLevelId() > 0) {
                EngineerLevel engineerLevel = engineerLevelMapper.selectById(engineer.getLevelId());
                vo.setLevelId(engineer.getLevelId());
                vo.setLevelName(engineerLevel.getName());
                vo.setLevelIcon(UrlUtils.toAbsoluteUrl(engineerLevel.getIcon()));
                vo.setLevelImage(UrlUtils.toAbsoluteUrl(engineerLevel.getImage()));
            }
        }

        // 分销会员开通方式
        if (config.getOpen().equals(1) && config.getOpenCondition().equals(2)) {
            isShowApplyPage = 1;
        }

        vo.setIsDistribution(isDistribution);
        vo.setIsShowApplyPage(isShowApplyPage);

        // 上级信息
        if (user.getFirstLeader() != null && user.getFirstLeader() > 0) {
            User firstLeader = userMapper.selectById(user.getFirstLeader());
            vo.setFirstLeader(firstLeader.getNickname());
        }

        // 粉丝数量
        Long totalFans = userMapper.selectCount(new QueryWrapper<User>().nested(wq -> wq.eq("first_leader", userId).or().eq("second_leader", userId)));

        // 今日预估
        BigDecimal todayEarnings = engineerOrderMapper.sum("earnings", new QueryWrapper<EngineerOrder>().eq("user_id", userId).ge("create_time", TimeUtils.today().get(0)).le("create_time", TimeUtils.today().get(1)).ne("status", EngineerEnum.ORDER_EXPIRED.getCode()));

        // 本月预估
        BigDecimal monthEarnings = engineerOrderMapper.sum("earnings", new QueryWrapper<EngineerOrder>().eq("user_id", userId).ge("create_time", TimeUtils.month().get(0)).le("create_time", TimeUtils.month().get(1)).ne("status", EngineerEnum.ORDER_EXPIRED.getCode()));

        // 累计佣金
        BigDecimal totalEarnings = engineerOrderMapper.sum("earnings", new QueryWrapper<EngineerOrder>().eq("user_id", userId).eq("status", EngineerEnum.ORDER_RETURNED.getCode()));

        // 订单数量
        Long totalOrder = engineerOrderMapper.selectCount(new QueryWrapper<EngineerOrder>().eq("user_id", userId));

        vo.setTodayEarnings(todayEarnings);
        vo.setMonthEarnings(monthEarnings);
        vo.setTotalEarnings(totalEarnings);
        vo.setTotalFans(totalFans);
        vo.setTotalOrder(totalOrder);
        vo.setApplyImage(config.getApplyImage());
        vo.setIsShowProtocol(config.getProtocolShow());
        return vo;
    }

    @Override
    public EngineerApplyDetailVo applyDetail(Integer userId) {
        EngineerApply engineerApply = engineerApplyMapper.selectOne(new QueryWrapper<EngineerApply>().eq("user_Id", userId).orderByDesc("id").last("limit 1"));

        if (engineerApply == null) {
            return null;
        }

        EngineerApplyDetailVo vo = new EngineerApplyDetailVo();
        BeanUtils.copyProperties(engineerApply, vo);
        vo.setStatusMsg(EngineerEnum.getApplyStatusMsg(engineerApply.getStatus()));
        vo.setCreateTime(TimeUtils.timestampToDate(engineerApply.getCreateTime()));

        DevRegion province = devRegionMapper.selectById(engineerApply.getProvince());
        DevRegion city = devRegionMapper.selectById(engineerApply.getCity());
        DevRegion district = devRegionMapper.selectById(engineerApply.getDistrict());

        vo.setProvinceMsg(province != null ? province.getName() : "");
        vo.setCityMsg(city != null ? city.getName() : "");
        vo.setDistrictMsg(district != null ? district.getName() : "");
        return vo;
    }

    @Override
    public void addEngineerData(Integer userId) {
        // 默认等级id
        Integer levelId = 0;
        // 默认等级
        EngineerLevel defaultLevel = engineerLevelMapper.selectOne(new QueryWrapper<EngineerLevel>()
                .eq("is_default", 1)
                .last("limit 1"));

        if (ObjectUtils.isEmpty(defaultLevel)) {
            EngineerLevel level = new EngineerLevel();
            level.setName("默认等级");
            level.setWeights(1);
            level.setIsDefault(1);
            level.setRemark("默认等级");
            // 升级关系，1-OR关系 2-AND关系
            level.setUpdateType(EngineerEnum.LEVEL_UPDATE_TYPE_OR.getCode());
            level.setCreateTime(TimeUtils.timestamp());
            level.setUpdateTime(TimeUtils.timestamp());
            engineerLevelMapper.insert(level);
            levelId = level.getId();
        } else {
            levelId = defaultLevel.getId();
        }

        // 新增分销信息表
        Engineer engineerData = new Engineer();
        engineerData.setUserId(userId);
        engineerData.setLevelId(levelId);
        engineerData.setIsEngineer(0);

        // 分销会员开通方式
        EngineerConfigVo config = config();
        //if (config.getOpen().equals(1) && config.getOpenCondition().equals(1)) {
            engineerData.setIsEngineer(1);
            engineerData.setEngineerTime(TimeUtils.timestamp());
        //}

        engineerData.setIsFreeze(0);
        engineerData.setRemark("");
        engineerData.setCreateTime(TimeUtils.timestamp());
        engineerData.setUpdateTime(TimeUtils.timestamp());
        engineerMapper.insert(engineerData);
    }
}
